// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) definits fieldsfirst ansi space safe 
// Source File Name:   EscapeSequence.java

package jones.behavior;

import jones.SimObject;
import jones.SimpleRobotInterface;

// Referenced classes of package jones.behavior:
//            TimeOut, CountOut

public class EscapeSequence
    implements SimObject
{
    private static class State
    {

        private final String name;
        public static final State START = new State("START");
        public static final State BACKUP = new State("BACKUP");
        public static final State SPIN_LEFT = new State("SPIN LEFT");
        public static final State SPIN_RIGHT = new State("SPIN RIGHT");
        public static final State FORWARD = new State("FORWARD");

        public String toString()
        {
            return name;
        }


        private State(String name)
        {
            this.name = name;
        }
    }


    private static final double MIN_ANGLE = 0.050000000000000003D;
    private static final int FRAMES_PER_SEC = 25;
    private static final int TURN_TIME = 25;
    private State state = null;
    private double backupTime = 0;
    private double forwardTime = 0;
    private double spin = 0;
    private double random = 0;
    private int leftSpinSpeed = 0;
    private TimeOut timeOut = null;
    private CountOut countOut = null;

    public EscapeSequence()
    {
        state = State.START;
        backupTime = 0.25D;
        forwardTime = 0.25D;
        spin = 180D;
        random = 45D;
        leftSpinSpeed = 0;
        timeOut = new TimeOut();
        countOut = new CountOut();
    }

    public double getRandom()
    {
        return random;
    }

    public void setRandom(double random)
    {
        this.random = random;
    }

    public double getBackupTime()
    {
        return backupTime;
    }

    public void setBackupTime(double backupTime)
    {
        this.backupTime = backupTime;
    }

    public double getSpin()
    {
        return spin;
    }

    public void setSpin(double spin)
    {
        this.spin = spin;
    }

    public double getForwardTime()
    {
        return forwardTime;
    }

    public void setForwardTime(double forwardTime)
    {
        this.forwardTime = forwardTime;
    }

    public void run(SimpleRobotInterface robot)
    {
        if (state == State.START)
            start(robot);
        else
        if (state == State.BACKUP)
            backup(robot);
        else
        if (state == State.SPIN_LEFT || state == State.SPIN_RIGHT)
            spin(robot);
        else
        if (state == State.FORWARD)
            forward(robot);
    }

    public void restart()
    {
        state = State.START;
    }

    public boolean isStarted()
    {
        return state != State.START;
    }

    public void start(SimpleRobotInterface robot)
    {
        state = State.START;
        backup(robot);
    }

    public void backup(SimpleRobotInterface robot)
    {
        if (state != State.BACKUP)
        {
            timeOut.start();
            state = State.BACKUP;
        }
        if (timeOut.isPast(backupTime))
        {
            spin(robot);
        } else
        {
            robot.setLeftWheelSpeed(-robot.getMaxWheelSpeed());
            robot.setRightWheelSpeed(-robot.getMaxWheelSpeed());
        }
    }

    public void spin(SimpleRobotInterface robot)
    {
        if (state != State.SPIN_LEFT && state != State.SPIN_RIGHT)
        {
            int spinAngle = (int)((Math.random() - 0.5D) * 2D * random + spin) % 360;
            if (spinAngle < 0)
                spinAngle += 360;
            if (spinAngle < 180)
            {
                state = State.SPIN_RIGHT;
                leftSpinSpeed = (int)((double)spinAngle / 1.25D);
            } else
            {
                state = State.SPIN_LEFT;
                leftSpinSpeed = (int)(-((double)(360 - spinAngle) / 1.25D));
            }
            countOut.start();
        }
        if (countOut.isPast(25) || leftSpinSpeed == 0)
        {
            forward(robot);
        } else
        {
            robot.setLeftWheelSpeed(leftSpinSpeed);
            robot.setRightWheelSpeed(-leftSpinSpeed);
        }
    }

    public void forward(SimpleRobotInterface robot)
    {
        if (state != State.FORWARD)
        {
            timeOut.start();
            state = State.FORWARD;
        }
        if (timeOut.isPast(forwardTime))
        {
            restart();
        } else
        {
            robot.setLeftWheelSpeed(robot.getMaxWheelSpeed());
            robot.setRightWheelSpeed(robot.getMaxWheelSpeed());
        }
    }

    public void update(double time)
    {
        timeOut.update(time);
        countOut.update(1);
    }

    public String getState()
    {
        return state.toString();
    }
}
